/**
 * pinia对象
 */

import router from '@/router';
import { defineStore, createPinia } from 'pinia';
import { computed, reactive, toRefs } from 'vue';

/**
 * 本地存储对象
 */
const local = window.localStorage;
/**
 * session存储对象
 */
const session = window.sessionStorage;

/**
 * 持久化插件
 * @param {Pinia} store pinia对象
 */
const persist = store => {
    /**
     * 需要Local storage存储的key
     */
    const LOCAL_KEYS = ['language'];
    /**
     * 需要session storage存储的key
     */
    const SESSION_KEYS = ['user', 'menus', 'flatMenu'];
    /**
     * 本地存储的key
     */
    const PERSIST_KEY = 'DOMAIN_MANAGER_PERSIST_KEY';
    /**
     * 本地存储的值
     */
    const localStr = local.getItem(PERSIST_KEY);
    /**
     * session存储的值
     */
    const sessionStr = session.getItem(PERSIST_KEY);

    store.$patch({
        ...(localStr ? JSON.parse(localStr) : {}),
        ...(sessionStr ? JSON.parse(sessionStr) : {})
    });

    store.$subscribe((mutation, state) => {
        // 要存储到localStorage的对象
        const localObj = LOCAL_KEYS.reduce((obj, key) => {
            obj[key] = state[key];
            return obj;
        }, {});
        // 要存储到sessionStorage的对象
        const sessionObj = SESSION_KEYS.reduce((obj, key) => {
            obj[key] = state[key];
            return obj;
        }, {});
        local.setItem(PERSIST_KEY, JSON.stringify(localObj));
        session.setItem(PERSIST_KEY, JSON.stringify(sessionObj));
    });
}

/**
 * 默认存储对象hook
 */
const useStore = defineStore('default', () => {
    /**
     * 所有的状态
     */
    const state = reactive({
        /**
         * 用户信息
         */
        user: {},
        /**
         * 菜单
         */
        menus: [],
        /**
         * 扁平化菜单
         */
        flatMenu: [],
        /**
         * 语言
         */
        language:'cn'
    });

    /**
     * token值
     */
    const token = computed(() => state.user?.token);
    /**
     * 是否已登录
     */
    const isLogin = computed(() => !!token.value);

    /**
     * 退出
     */
    const exit = route => {
        state.user = {};
        router.push({ name: route || 'login' });
    }

    return {
        ...toRefs(state),
        exit,
        token,
        isLogin,
    }
});

/**
 * pinia对象
 */
const pinia = createPinia();
/**
 * store对象
 */
const store = useStore(pinia);
/**
 * 持久化
 */
persist(store);

/**
 * 安装方法
 * @param {*} app App对象
 */
const install = app => {
    app.use(pinia);
    app.config.globalProperties.$store = store;
}

export {
    install,
    store
}